﻿using Coolzon.Common;
using Coolzon.Realtime.Contracts;
using Coolzon.Realtime.ServerApp.ServiceImplement;
using CPPEI.Coolzon.Server;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.Text;

namespace Coolzon.Realtime.ServerApp
{
    class Program
    {
        private static ServiceHost s_mainServiceHost;
        //private static ServiceHost s_dataServiceHost;
        //private static ServiceHost s_syncServiceHost;
        //private static IWCFServiceHost s_publishServiceHost;

        //private static API.ApiService s_apiService;

        //private static EventReceiver _eventReceiver;
        //private static ServiceHost s_updateServiceHost;

        static void Main(string[] args)
        {
            AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;

            //Logger.Init(CZEnvironment.GetLoggerConfigFilePath());
            if (!ConfigLoader.Load())
            {
                // 程序配置文件加载失败,关闭程序
                return;
            }
            Logger.InitByLogDirectory(Config.GetLogDirectory());
            /*
            CZEnvironment.Instance.Init(CZEnvironment.GetEnvironmentFilePath());

            _eventReceiver = new EventReceiver();
            PublishEventBus.Register(_eventReceiver);

            LoadSolutions();

            VerifySolutions();

            HostApiService();
            HostSyncService();
            HostDataService();
            s_publishServiceHost = new Coolzon.ServiceImp.WCFPublishServiceHost();
            if (!s_publishServiceHost.Open())
            {
                Logger.Error("Server", "启动发布服务失败!");
            }*/
            HostMainService();
            //HostUpdateService();

            //HeartbeatThread heartbeatThread = new HeartbeatThread();
            //heartbeatThread.Start();

            InputLoop();

            //heartbeatThread.Stop();

            StopMainService();
            /*
            s_publishServiceHost.Close();
            StopDataService();
            StopSyncService();
            StopApiService();
            //StopUpdateService();
            */
            Logger.InfoToTag("Server", "服务器关闭");
        }

        static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            try
            {
                if (e.ExceptionObject is Exception)
                {
                    Logger.ErrorToTag("Unhandled", ((Exception)e.ExceptionObject).Message);
                }
            }
            catch (Exception ex)
            {
                Logger.ErrorToTag("Unhandled", ex.Message);
            }
        }
        /*
        private static void HostApiService()
        {
            Logger.InfoToTag("Server", "API服务启动中...");
            Configuration.Server.ServiceConfig serviceConfig = Configuration.Server.Config.Host.GetServiceConfig("ApiService");
            if (serviceConfig == null)
            {
                Logger.ErrorToTag("Server", "API服务启动失败，未发现ApiService配置信息");
            }
            else
            {
                try
                {
                    s_apiService = new API.ApiService();
                    s_apiService.Start(serviceConfig.IP, serviceConfig.Port);
                    Logger.InfoToTag("Server", "API服务启动成功 ip:{0}, port:{1}", serviceConfig.IP, serviceConfig.Port);
                }
                catch (Exception ex)
                {
                    Logger.ErrorToTag("Server", "API服务启动失败 ip:{0}, port:{1}, ex:{2}", serviceConfig.IP, serviceConfig.Port, ex);
                }
            }
        }

        private static void StopApiService()
        {
            Logger.InfoToTag("Server", "API服务关闭中...");
            if (s_apiService != null)
            {
                s_apiService.Stop();
            }
            Logger.InfoToTag("Server", "API服务关闭完成");
        }

        public static void VerifySolutions()
        {
            Logger.InfoToTag("Server", "验证方案文件版本信息...");

            if (Coolzon.Server.CacheData.ServerData.Instance.SolutionList != null)
            {
                for (int index = 0; index < Coolzon.Server.CacheData.ServerData.Instance.SolutionList.Count; index++)
                {
                    // 扫描方案的文件生成最新的方案文件版本信息的记录文件
                    SyncService.VerifySolutions(Coolzon.Server.CacheData.ServerData.Instance.SolutionList[index].Name);
                }
            }

            Logger.InfoToTag("Server", "验证方案文件版本信息完毕");
        }

        public static void LoadSolutions()
        {
            Logger.InfoToTag("Server", "加载方案列表...");

            // 读取方案到内存中
            CPPEI.Coolzon.Server.CacheData.ServerData.Instance.SolutionList = CPPEI.Coolzon.Metadata.SolutionXmlProxy.LoadSolutionList(Runtime.Metadata.Storage.GetSolutionSummaryFile());

            if (CPPEI.Coolzon.Server.CacheData.ServerData.Instance.SolutionList != null)
            {
                foreach (var solutionRef in CPPEI.Coolzon.Server.CacheData.ServerData.Instance.SolutionList)
                {
                    Logger.InfoToTag("Server", "方案:{0},Caption:{1},Version:{2},RuntimeVersion:{3}", solutionRef.Name, solutionRef.Caption, solutionRef.Version, solutionRef.RuntimeVersion);
                }
            }
            else
            {
                Logger.InfoToTag("Server", "加载方案列表完毕,没有发现任何方案");
            }
        }

        private static void HostSyncService()
        {
            Logger.InfoToTag("Server", "配置同步服务启动中...");
            Configuration.Server.ServiceConfig serviceConfig = Configuration.Server.Config.Host.GetServiceConfig("SyncService");
            Uri baseAddress = new Uri(string.Format("net.tcp://{0}:{1}/{2}/", serviceConfig.IP, serviceConfig.Port, serviceConfig.Path));

            s_syncServiceHost = new ServiceHost(typeof(SyncService), baseAddress);
            Binding binding = new NetTcpBinding();
            (binding as NetTcpBinding).ReceiveTimeout = TimeSpan.FromSeconds(300);
            (binding as NetTcpBinding).SendTimeout = TimeSpan.FromSeconds(300);
            (binding as NetTcpBinding).MaxBufferSize = 1024 * 1024 * 1024;
            (binding as NetTcpBinding).MaxReceivedMessageSize = 1024 * 1024 * 1024;
            (binding as NetTcpBinding).Security.Mode = SecurityMode.None;
            ServiceMetadataBehavior serviceMetadataBehavior = new ServiceMetadataBehavior();
            s_syncServiceHost.Description.Behaviors.Add(serviceMetadataBehavior);
            if (serviceConfig.MetadataGet)
            {
                Logger.InfoToTag("Server", "配置同步服务元数据获取开关:开启");
                Logger.InfoToTag("Server", "配置同步服务元数据获取地址:{0}mex", baseAddress);
                s_syncServiceHost.AddServiceEndpoint(typeof(IMetadataExchange), MetadataExchangeBindings.CreateMexTcpBinding(), "mex");
            }
            else
            {
                Logger.InfoToTag("Server", "配置同步服务元数据获取开关:关闭");
            }

            s_syncServiceHost.AddServiceEndpoint(typeof(ISyncService), binding, baseAddress);
            Logger.InfoToTag("Server", "配置同步服务地址:{0}", baseAddress);

            try
            {
                s_syncServiceHost.Open();
                Logger.InfoToTag("Server", "配置同步服务启动成功");
            }
            catch (Exception ex)
            {
                Logger.Error("Server", string.Format("配置同步服务启动失败{0}{1}", Environment.NewLine, ex));
            }
        }

        private static void HostDataService()
        {
            Logger.InfoToTag("Server", "数据服务启动中...");
            Configuration.Server.ServiceConfig serviceConfig = Configuration.Server.Config.Host.GetServiceConfig("DataService");
            Uri baseAddress = new Uri(string.Format("net.tcp://{0}:{1}/{2}/", serviceConfig.IP, serviceConfig.Port, serviceConfig.Path));

            s_dataServiceHost = new ServiceHost(typeof(ServiceImplement.DataService), baseAddress);
            Binding binding = new NetTcpBinding();
            (binding as NetTcpBinding).ReceiveTimeout = TimeSpan.FromSeconds(300);
            (binding as NetTcpBinding).SendTimeout = TimeSpan.FromSeconds(300);
            (binding as NetTcpBinding).Security.Mode = SecurityMode.None;
            ServiceMetadataBehavior serviceMetadataBehavior = new ServiceMetadataBehavior();
            s_dataServiceHost.Description.Behaviors.Add(serviceMetadataBehavior);

            ServiceThrottlingBehavior serviceThrottlingBehavior = new ServiceThrottlingBehavior();
            serviceThrottlingBehavior.MaxConcurrentSessions = 10000;
            serviceThrottlingBehavior.MaxConcurrentCalls = 10000;
            serviceThrottlingBehavior.MaxConcurrentInstances = 20000;
            s_dataServiceHost.Description.Behaviors.Add(serviceThrottlingBehavior);

            if (serviceConfig.MetadataGet)
            {
                Logger.InfoToTag("Server", "数据服务元数据获取开关:开启");
                Logger.InfoToTag("Server", "数据服务元数据获取地址:{0}mex", baseAddress);
                s_dataServiceHost.AddServiceEndpoint(typeof(IMetadataExchange), MetadataExchangeBindings.CreateMexTcpBinding(), "mex");
            }
            else
            {
                Logger.InfoToTag("Server", "数据服务元数据获取开关:关闭");
            }

            s_dataServiceHost.AddServiceEndpoint(typeof(IDataService), binding, baseAddress);
            Logger.InfoToTag("Server", "数据服务地址:{0}", baseAddress);

            try
            {
                s_dataServiceHost.Open();
                Logger.InfoToTag("Server", "数据服务启动成功");
            }
            catch (Exception ex)
            {
                Logger.Error("Server", string.Format("数据服务启动失败{0}{1}", Environment.NewLine, ex));
            }
        }
        */
        private static void HostMainService()
        {
            Logger.InfoToTag("Server", "主服务启动中...");
            Uri baseAddress = new Uri(string.Format("net.tcp://{0}:{1}/MainService/", Config.Current.IP, Config.Current.Port));

            s_mainServiceHost = new ServiceHost(typeof(MainService), baseAddress);
            Binding binding = new NetTcpBinding();
            (binding as NetTcpBinding).Security.Mode = SecurityMode.None;
            ServiceMetadataBehavior serviceMetadataBehavior = new ServiceMetadataBehavior();
            s_mainServiceHost.Description.Behaviors.Add(serviceMetadataBehavior);

            //if (serviceConfig.MetadataGet)
            //{
            //    Logger.InfoToTag("Server", "主服务元数据获取开关:开启");
            //    Logger.InfoToTag("Server", "主服务元数据获取地址:{0}mex", baseAddress);
            //    s_mainServiceHost.AddServiceEndpoint(typeof(IMetadataExchange), MetadataExchangeBindings.CreateMexTcpBinding(), "mex");
            //}
            //else
            //{
            //    Logger.InfoToTag("Server", "主服务元数据获取开关:关闭");
            //}

            s_mainServiceHost.AddServiceEndpoint(typeof(IMainService), binding, baseAddress);
            Logger.InfoToTag("Server", string.Format("主服务地址:{0}", baseAddress));

            try
            {
                s_mainServiceHost.Open();
                Logger.InfoToTag("Server", "主服务启动成功");
            }
            catch (Exception ex)
            {
                Logger.ErrorToTag("Server", string.Format("主服务启动失败ex:{0}", ex));
            }
        }

        //private static void HostUpdateService()
        //{
        //    Logger.InfoToTag("Server", "更新服务启动中...");
        //    Configuration.Server.ServiceConfig serviceConfig = Configuration.Server.Config.Host.GetServiceConfig("UpdateService");
        //    Uri baseAddress = new Uri(string.Format("net.tcp://{0}:{1}/{2}/", serviceConfig.IP, serviceConfig.Port, serviceConfig.Path));

        //    s_updateServiceHost = new ServiceHost(typeof(UpdateService), baseAddress);
        //    Binding binding = new NetTcpBinding();
        //    (binding as NetTcpBinding).Security.Mode = SecurityMode.None;
        //    ServiceMetadataBehavior serviceMetadataBehavior = new ServiceMetadataBehavior();
        //    s_updateServiceHost.Description.Behaviors.Add(serviceMetadataBehavior);

        //    if (serviceConfig.MetadataGet)
        //    {
        //        Logger.InfoToTag("Server", "更新服务元数据获取开关:开启");
        //        Logger.InfoToTag("Server", "更新服务元数据获取地址:{0}mex", baseAddress);
        //        s_updateServiceHost.AddServiceEndpoint(typeof(IMetadataExchange), MetadataExchangeBindings.CreateMexTcpBinding(), "mex");
        //    }
        //    else
        //    {
        //        Logger.InfoToTag("Server", "发布服务元数据获取开关:关闭");
        //    }

        //    s_updateServiceHost.AddServiceEndpoint(typeof(IUpdateService), binding, baseAddress);
        //    Logger.InfoToTag("Server", "更新服务地址:{0}", baseAddress);

        //    try
        //    {
        //        s_updateServiceHost.Open();
        //        Logger.InfoToTag("Server", "更新服务启动成功");
        //    }
        //    catch (Exception ex)
        //    {
        //        Logger.ErrorToTag("Server", string.Format("更新服务启动失败{0}{1}", Environment.NewLine, ex));
        //    }
        //}

        private static void StopMainService()
        {
            Logger.InfoToTag("Server", "主服务器关闭中...");
            try
            {
                s_mainServiceHost.Close();
                Logger.InfoToTag("Server", "主服务关闭成功");
            }
            catch (Exception ex)
            {
                Logger.ErrorToTag("Server", string.Format("主服务关闭失败,ex:{0}", ex));
            }
        }

        //private static void StopUpdateService()
        //{
        //    Logger.InfoToTag("Server","更新服务器关闭中...");
        //    try
        //    {
        //        s_updateServiceHost.Close();
        //        Logger.InfoToTag("Server", "更新服务关闭成功");
        //    }
        //    catch (Exception ex)
        //    {
        //        Logger.ErrorToTag("Server", string.Format("更新服务关闭失败{0}{1}", Environment.NewLine, ex));
        //    }
        //}
        /*
        private static void StopDataService()
        {
            Logger.InfoToTag("Server", "数据服务器关闭中...");
            try
            {
                s_dataServiceHost.Close();
                Logger.InfoToTag("Server", "数据服务关闭成功");
            }
            catch (Exception ex)
            {
                Logger.ErrorToTag("Server", string.Format("数据服务关闭失败{0}{1}", Environment.NewLine, ex));
            }
        }

        private static void StopSyncService()
        {
            Logger.InfoToTag("Server", "同步服务器关闭中...");
            try
            {
                s_syncServiceHost.Close();
                Logger.InfoToTag("Server", "同步服务关闭成功");
            }
            catch (Exception ex)
            {
                Logger.ErrorToTag("Server", string.Format("同步服务关闭失败{0}{1}", Environment.NewLine, ex));
            }
        }
        */
        private static void InputLoop()
        {
            string cmd = Console.ReadLine().ToUpper();
            while (!ConsoleCMD.Execute(cmd))
            {
                cmd = Console.ReadLine().ToUpper();
            }
        }

        //#region license

        //private static void ShowTrivalAlart()
        //{
        //    string fileName = string.Format("{0}CPPEI.Coolzon.TrivalAlert.exe", AppDomain.CurrentDomain.BaseDirectory);
        //    Process[] processArr = Process.GetProcessesByName("CPPEI.Coolzon.TrivalAlert");
        //    for (int index = 0; index < processArr.Length; index++)
        //    {
        //        if (string.Equals(processArr[index].MainModule.FileName, fileName, StringComparison.CurrentCultureIgnoreCase))
        //        {
        //            processArr[index].Kill();
        //        }
        //    }
        //    // 启动
        //    ProcessStartInfo startInfo = new ProcessStartInfo();
        //    startInfo.Arguments = string.Format("{0} {1}", License.ExpireTime.Value.ToString("yyyy-MM-dd"), License.SerialNumber);
        //    startInfo.FileName = fileName;
        //    Process.Start(startInfo);
        //}

        //private static void CloseTrivalAlart()
        //{
        //    string fileName = string.Format("{0}CPPEI.Coolzon.TrivalAlert.exe", AppDomain.CurrentDomain.BaseDirectory);
        //    Process[] processArr = Process.GetProcessesByName("CPPEI.Coolzon.TrivalAlert");
        //    for (int index = 0; index < processArr.Length; index++)
        //    {
        //        if (string.Equals(processArr[index].MainModule.FileName, fileName, StringComparison.CurrentCultureIgnoreCase))
        //        {
        //            processArr[index].Kill();
        //        }
        //    }
        //}

        ///// <summary>
        ///// 验证license文件
        ///// </summary>
        ///// <returns>true:验证通过,false:验证失败</returns>
        //private static bool ValidateLICFile()
        //{
        //    string encryptionKey = "cPPEI_cOolzOn";
        //    License.SerialNumber = DSAL.SN.GetSerialNumber("coolzonx1.4", "server");
        //    string licFilePath = string.Format("{0}\\coolzon.lic", AppDomain.CurrentDomain.BaseDirectory);
        //    string sn = null;
        //    Dictionary<string, string> kv = DSAL.LisenceFile.Load(licFilePath, encryptionKey, out sn);
        //    if (kv != null)
        //    {
        //        if (string.Equals(sn, License.SerialNumber))
        //        {
        //            License.ExpireTime = Convert.ToDateTime(kv["EXPIREDATE"]);
        //            License.ClientCount = Convert.ToInt32(kv["CLIENTCOUNT"]);
        //            License.IsTrial = Convert.ToInt32(kv["EDITION"]);
        //            // 存储到系统目录
        //            PublishLICToSystem(kv);
        //            return true;
        //        }
        //    }

        //    if (ValidateSystemLIC())
        //    {
        //        return true;
        //    }
        //    //  
        //    CreateTrivalLicense();
        //    return false;
        //}

        ///// <summary>
        ///// 验证系统目录里的license文件
        ///// </summary>
        //private static bool ValidateSystemLIC()
        //{
        //    string encryptionKey = "cPPEI_cOolzOn";
        //    string sn = null;
        //    Dictionary<string, string> kv = DSAL.LisenceFile.LoadFromSystemDir("cppei", "coolzon-server", encryptionKey, out sn);
        //    if (kv != null)
        //    {
        //        License.ExpireTime = Convert.ToDateTime(kv["EXPIREDATE"]);
        //        License.ClientCount = Convert.ToInt32(kv["CLIENTCOUNT"]);
        //        License.IsTrial = Convert.ToInt32(kv["EDITION"]);

        //        return true;
        //    }
        //    return false;
        //}

        ///// <summary>
        ///// 发布license 文件到系统目录
        ///// </summary>
        //private static void PublishLICToSystem(Dictionary<string, string> kv)
        //{
        //    string encryptionKey = "cPPEI_cOolzOn";
        //    DSAL.LisenceFile.SaveToSystemDir("cppei", "coolzon-server", encryptionKey, License.SerialNumber, kv);
        //}

        ///// <summary>
        ///// 创建试用版license文件
        ///// </summary>
        //private static void CreateTrivalLicense()
        //{
        //    string encryptionKey = "cPPEI_cOolzOn";
        //    Dictionary<string, string> kv = new Dictionary<string, string>();
        //    kv.Add("EXPIREDATE", DateTime.Now.AddDays(180).ToString("yyyy-MM-dd"));
        //    kv.Add("CLIENTCOUNT", "1");
        //    // trival
        //    kv.Add("EDITION", "1");
        //    DSAL.LisenceFile.SaveToSystemDir("cppei", "coolzon-server", encryptionKey, License.SerialNumber, kv);

        //    License.ExpireTime = DateTime.Now.AddDays(180);
        //    License.ClientCount = 1;
        //    License.IsTrial = License.TrialEdition;
        //}
        //#endregion
    }
}
